home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / NR4SUBR.C < prev    next >
Text File  |  1993-08-09  |  5KB  |  199 lines

  1. /*
  2.  * nr4subr.c:  subroutines for net/rom transport layer.
  3.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  4.  * non-commercial distribution only.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "config.h"
  10. #ifdef NETROM
  11. #include "mbuf.h"
  12. #include "timer.h"
  13. #include "ax25.h"
  14. #include "netrom.h"
  15. #include "nr4.h"
  16. #include <ctype.h>
  17.  
  18. /* Get a free circuit table entry, and allocate a circuit descriptor.
  19.  * Initialize control block circuit number and ID fields.
  20.  * Return a pointer to the circuit control block if successful,
  21.  * NULLNR4CB if not.
  22.  */
  23. struct nr4cb *
  24. new_n4circ()
  25. {
  26.     int i ;
  27.     struct nr4cb *cb ;
  28.  
  29.     for (i = 0 ; i <  NR4MAXCIRC ; i++)        /* find a free circuit */
  30.         if (Nr4circuits[i].ccb == NULLNR4CB)
  31.             break ;
  32.  
  33.     if (i == NR4MAXCIRC)
  34.         return NULLNR4CB;
  35.  
  36.     Nr4circuits[i].ccb = mxallocw(sizeof(struct nr4cb));
  37.  
  38.     cb = Nr4circuits[i].ccb;
  39.     cb->mynum = i ;
  40.     cb->myid = Nr4circuits[i].cid ;
  41.  
  42.     /* set l4 inactivity timer to 30 mins */
  43.     cb->inactivity.func = (void (*) __ARGS((void *))) reset_nr4;
  44.     cb->inactivity.arg = cb;
  45.     set_timer(&cb->inactivity,1800000L);
  46.  
  47.     return cb ;
  48. }
  49.  
  50. /* Set the window size for a circuit and allocate the buffers for
  51.  * the transmit and receive windows.  Set the control block window
  52.  * parameter.  Return 0 if successful, -1 if not.
  53.  */
  54. int
  55. init_nr4window(struct nr4cb *cb,unsigned window)
  56. {
  57.     if (window == 0 || window > NR4MAXWIN) /* reject silly window sizes */
  58.         window = 1;
  59.  
  60.     cb->txbufs = cxallocw(window,sizeof(struct nr4txbuf));
  61.     cb->rxbufs = cxallocw(window,sizeof(struct nr4rxbuf));
  62.  
  63.     cb->window = window ;
  64.     return 0 ;
  65. }
  66.  
  67. /* Free a circuit.  Deallocate the control block and buffers, and
  68.  * increment the circuit ID.  No return value.
  69.  */
  70. void
  71. free_n4circ(struct nr4cb *cb)
  72. {
  73.     unsigned circ = cb->mynum;
  74.  
  75.     if (cb == NULLNR4CB)
  76.         return ;
  77.  
  78.     if (cb->txbufs != (struct nr4txbuf *)0)
  79.         xfree(cb->txbufs) ;
  80.  
  81.     if (cb->rxbufs != (struct nr4rxbuf *)0)
  82.         xfree(cb->rxbufs) ;
  83.  
  84.     stop_timer(&cb->inactivity);    /* stop it */
  85.  
  86.     /* Better be safe than sorry: */
  87.     free_q(&cb->txq) ;
  88.     free_q(&cb->rxq) ;
  89.  
  90.     xfree(cb) ;
  91.  
  92.     if (circ > NR4MAXCIRC)        /* Shouldn't happen. */
  93.         return ;
  94.  
  95.     Nr4circuits[circ].ccb = NULLNR4CB ;
  96.     Nr4circuits[circ].cid++ ;
  97.     return;
  98. }
  99.  
  100. /* See if any open circuit matches the given parameters.  This is used
  101.  * to prevent opening multiple circuits on a duplicate connect request.
  102.  * Returns the control block address if a match is found, or NULLNR4CB
  103.  * otherwise.
  104.  */
  105. struct nr4cb *
  106. match_n4circ(index, id, user, node)
  107. int index ;                    /* index of remote circuit */
  108. int id ;                    /* id of remote circuit */
  109. char *user ;    /* address of remote user */
  110. char *node ;    /* address of originating node */
  111. {
  112.     int i ;
  113.     struct nr4cb *cb ;
  114.  
  115.     for (i = 0 ; i < NR4MAXCIRC ; i++) {
  116.         if ((cb = Nr4circuits[i].ccb) == NULLNR4CB)
  117.             continue ;        /* not an open circuit */
  118.         if (cb->yournum == index && cb->yourid == id
  119.           && addreq(cb->remote.user,user)
  120.           && addreq(cb->remote.node,node))
  121.             return cb ;
  122.     }
  123.     /* if we get to here, we didn't find a match */
  124.     return NULLNR4CB ;
  125. }
  126.  
  127. /* Validate the index and id of a local circuit, returning the control
  128.  * block if it is valid, or NULLNR4CB if it is not.
  129.  */
  130. struct nr4cb *
  131. get_n4circ(index, id)
  132. int index ;                /* local circuit index */
  133. int id ;                /* local circuit id */
  134. {
  135.     struct nr4cb *cb ;
  136.  
  137.     if (index >= NR4MAXCIRC || (cb = Nr4circuits[index].ccb) == NULLNR4CB)
  138.         return NULLNR4CB ;
  139.  
  140.     return (cb->myid == id) ? cb : NULLNR4CB ;
  141. }
  142.  
  143. /* Return 1 if b is "between" (modulo the size of an unsigned char)
  144.  * a and c, 0 otherwise.
  145.  */
  146. int
  147. nr4between(unsigned a,unsigned b,unsigned c)
  148. {
  149.     return ((a <= b && b < c) || (c < a && a <= b) || (b < c && c < a)) ? 1 : 0;
  150. }
  151.  
  152. /* Set up default timer values, etc., in newly connected control block.
  153.  */
  154. void
  155. nr4defaults(struct nr4cb *cb)
  156. {
  157.     int i ;
  158.     struct timer *t ;
  159.  
  160.     if (cb == NULLNR4CB)
  161.         return ;
  162.  
  163.     /* Set up the ACK and CHOKE timers */
  164.  
  165.     set_timer(&cb->tack,Nr4acktime * 1000) ;
  166.     cb->tack.func = nr4ackit ;
  167.     cb->tack.arg = cb ;
  168.  
  169.     set_timer(&cb->tchoke,Nr4choketime * 1000) ;
  170.     cb->tchoke.func = nr4unchoke ;
  171.     cb->tchoke.arg = cb ;
  172.  
  173.     cb->rxpastwin = cb->window ;
  174.  
  175.     /* Don't actually set the timers, since this is done in nr4sbuf */
  176.     for (i = 0 ; i < cb->window ; i++) {
  177.         t = &cb->txbufs[i].tretry ;
  178.         t->func = nr4txtimeout ;
  179.         t->arg = cb ;
  180.     }
  181.     return;
  182. }
  183.  
  184. /* See if this control block address is valid */
  185.  
  186. int
  187. nr4valcb(struct nr4cb *cb)
  188. {
  189.     int i;
  190.  
  191.     if (cb != NULLNR4CB) {
  192.         for (i = 0 ; i < NR4MAXCIRC ; i++)
  193.             if (Nr4circuits[i].ccb == cb)
  194.                 return 1 ;
  195.     }
  196.     return 0 ;
  197. }
  198.  
  199. #endif /* NETROM */